home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FishMarket 1.0
/
FishMarket v1.0.iso
/
fishies
/
476-500
/
disk_496
/
ruler
/
workbench
/
ruler.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-05-06
|
15KB
|
637 lines
/* RULER - Workbench Version
*
* See Ruler.doc for directions
*
* Revision History:
* -----------------
*
* Version 5.0 21-Apr-1991 ©1991 Dave Schreiber, Chad Netzer, and
* Thad Floryan
* Based upon code from:
*
* Version 4.0 29-Dec-1989 ©1989 Chad Netzer and Thad Floryan
*
* Based upon code, idea, and logic from:
*
* Version 1.0 7-Nov-1988 ©1988 Thad Floryan
*
* Revision history:
* 21-April-1991 - (Ver. 5.00) (DKS):
* 1 Window is sized to make room for > 8 point fonts in the
* title bar and main window (for compatibility with AmigaOS
* 2.x)
* 2 Added the ability to put Ruler's window on any screen at
* will.
* 3 Added the ability to get the font scale from any window.
* 4 Added menus for:
* * About
* * Quit
* * Change Screen (#2)
* * Change Font (#3)
* These menus are layed out by the 2.x function
* LayoutMenusA(). This function is called only if Ruler
* is running under 2.0 or later (i.e. Ruler is 1.3
* compatible).
*
* 29-December-1989 - (Ver. 4.0) - Added an offset so that you can
* just stick the window on the left edge of the workbench screen,
* and it will automatically be lined up with the characters.
* Fixed some more minor bugs and rearranged the code a bit.
* Added ARP support for those who want it. (CFN)
*
* 09-March-1989 - (Ver. 3.1) - Fixed a visual bug so that scale can
* no longer be less than eight. (CFN)
*
* 06-Dec-1988 - (Ver. 3.0) - Added support for measuring fonts of
* varying widths (selectable scale). (CFN)
*
* 22-Nov-1988 - (Ver. 2.2) - More adjustments to code, No major
* changes. Program size is slightly smaller. (CFN)
*
* 14-Nov-1988 - (Ver. 2.1) - Fixed a few minor (harmless) bugs. The
* right edge of the ruler is now always redrawn after resizing.
* I got rid of that GOTO statement (which in 'C', is considered a
* bug. :-) Version 2.1 now lets you open a ruler to be as low as
* 12 characters wide, which 2.0 only advertised. (CFN)
*
* 13-Nov-1988 - (Ver. 2.0) - I added minor enhancements, most
* noteably, the ability to resize the window, and support for
* overscanned screens. (CFN)
*
*
* Feel welcome to use this program for any non-commercial purposes or
* for your personal learning. Commercial users are requested to contact
* Thad at either:
*
* UUCP: thad@cup.portal.com (OR) ..!sun!portal!cup.portal.com!thad
* BBS: BBS-JC, 415/961-7250 (300/1200/2400), "Thad Floryan" | "SYSOP"
*
* Chad at:
*
* UUCP: chad@ucscb.ucsc.edu (during school term)
* UUCP: chad@cup.portal.com (holidays, summer, etc.)
* BBS: BBS-JC, 415/961-7250 (300/1200/2400), "Chad Netzer"
*
* or Dave at:
*
* UUCP: davids@ucscb.ucsc.edu
* BBS: BBS-JC, "Dave Schreiber"
*
*
* Building instructions (SAS/C V5.10):
*
* lc -Lcd -v Ruler
*
*/
#include <exec/types.h>
#include <exec/memory.h>
#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>
#include <graphics/gfxbase.h>
#include <workbench/startup.h>
#include <clib/wb_protos.h>
#define AMIGA_2.0 1 /*Delete if include files for 2.0 or later are*/
/*not available*/
#ifdef AMIGA_2.0
#include <utility/tagitem.h>
struct TagItem menuTag[] =
{
{TAG_DONE,NULL}
};
#endif
#include "GUI.h"
/*Some constants*/
#define HEIGHT titleBarHeight+textHeight-2
#define DEF_HEIGHT 12L+HEIGHT
#define RULER_MARK_Y 11L+HEIGHT
#define OFFSET_START_Y 2L+titleBarHeight
#define BIG_TIC_Y 5L+HEIGHT
#define SMALL_TIC_Y 9L+HEIGHT
#define TEXT_Y 3L+HEIGHT
#define DRAW_AREA_Y 3L+titleBarHeight
#define DRAW_AREA_HEIGHT 24L+textHeight
#define NEW(typ) AllocMem((ULONG)sizeof(typ), MEMF_CLEAR)
#define FREE(p,typ) FreeMem(p,(ULONG)sizeof(typ))
#define ever (;;) /* used for infinite loops */
#define FATAL 20 /* exit code */
#define WARN 10 /* exit code */
#define NORMAL 0 /* exit code */
#define LEFT_OFFSET 3L /* "dead space" on left side of ruler margin */
extern void *OpenLibrary();
extern void *OpenWindow();
extern void *GetMsg();
extern void *AllocMem();
extern void ReplyMsg();
/* Prototypes for functions defined in ruler5.c */
void __regargs release_resources(void);
void __regargs error_exit(void);
int __regargs handleMenu(USHORT NUM);
void __regargs printAboutWindow(void);
void __regargs changeFSize(void);
void __regargs changeScreen(void);
void __regargs readWBArgs(void);
UWORD titleBarHeight,textHeight,textWidth,screenWidth;
struct NewWindow window_def =
{
0, 0, /* Initial LeftEdge, TopEdge */
241, 17, /* Default pixel-width, pixel-height */
0, 1, /* DetailPen, BlockPen */
CLOSEWINDOW | /* IDCMP flags */
MENUPICK |
NEWSIZE,
WINDOWDRAG | /* window flags */
WINDOWDEPTH |
WINDOWCLOSE |
WINDOWSIZING |
ACTIVATE |
SMART_REFRESH |
NOCAREREFRESH,
NULL, /* Gadget list */
NULL, /* checkmark stuff */
NULL, /* window title (to be filled in later) */
NULL, /* custom screen pointer */
NULL, /* bitmap pointer */
97 + LEFT_OFFSET, 0, /* Minwidth, no MinHeight */
-1, 0, /* no MaxWidth, MaxHeight */
CUSTOMSCREEN /* screen type */
};
struct Window *window;
struct RastPort *rp;
struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
struct Library *GadToolsBase;
struct Library *IconBase;
struct Screen *screen;
struct IntuiMessage *sys_message;
ULONG class;
USHORT code;
int resource_state;
long fsize; /* The font size of ruler scale */
long w; /* character width of ruler */
APTR visualInfo;
char *version =
"Text Ruler V5.00 (Workbench) 21-Apr-91 ©1991 ";
extern struct WBStartup *WBenchMsg;
/**********************************************************************/
_main ()
{
long fivec; /* pixel size of five chars */
long w_lim; /* pixel width (w * fsize) */
long x; /* present window x coordinate */
long y; /* present window y coordinate */
char buf[5];
int redoWindow; /*Boolean flag*/
resource_state = 0;
/*
* Open Intuition and Graphics so we can get screen size and
* default font information.
*/
if((IntuitionBase = OpenLibrary ("intuition.library", NULL))==NULL)
error_exit();
++resource_state;
if((GfxBase = OpenLibrary ("graphics.library", NULL))==NULL)
error_exit();
++resource_state;
GadToolsBase = OpenLibrary("gadtools.library",NULL);
if(GadToolsBase)
window_def.IDCMPFlags|=(ACTIVEWINDOW|INACTIVEWINDOW);
/*
* Get WorkBench screen information
*/
screen=window_def.Screen=IntuitionBase->ActiveScreen;
w = 30L; /* default ruler is 30 chars for a filename */
/*Get default scale*/
fsize=textWidth=GfxBase->DefaultFont->tf_XSize;
readWBArgs();
w_lim = w * fsize;
/*
* Main loop
*/
for ever
{
/* Get width of screen
*/
screenWidth=screen->Width;
/* Determine spacing from current font information
*/
titleBarHeight = screen->Font->ta_YSize;
textHeight = GfxBase->DefaultFont->tf_YSize;
/*
* Now calculate window sizing and placement parameters and setup title.
*/
window_def.Width = w_lim + LEFT_OFFSET + 1;
window_def.Height = DEF_HEIGHT;
window_def.Title = (UBYTE *)version;
/*
* Shorten the window if it would be wider than the screen
*/
if (window_def.Width > screenWidth )
{
window_def.Width = screenWidth;
w_lim = (window_def.Width) - 1 - LEFT_OFFSET;
}
/*
* Open the ruler display window.
*/
window = OpenWindow (&window_def);
if (window == NULL)
{
error_exit();
}
++resource_state;
/*
* Set screen and window titles
*/
SetWindowTitles(window,version,"Text Ruler V5.00");
/*
* If running under 2.0 or later, adjust menu spacing information
* to compensate for a non-8 point font size.
*/
if(GadToolsBase != NULL)
{
visualInfo = (APTR)GetVisualInfoA(screen,menuTag);
LayoutMenusA(&Menu1,visualInfo,menuTag);
FreeVisualInfo(visualInfo);
}
/*
* Install menus
*/
SetMenuStrip(window,&Menu1);
/*
* Get pointer to raster port.
*/
rp = window -> RPort;
/*
* Inner loop (loop until the window needs to be closed and another
* opened).
*/
redoWindow=FALSE;
while(!redoWindow)
{
redoWindow=FALSE;
fivec = 5L * fsize;
/*
* Use RectFill to blank the window area and set pen for drawing.
*/
SetAPen(rp, NULL);
RectFill(rp, LEFT_OFFSET+1, DRAW_AREA_Y, w_lim + LEFT_OFFSET-1,
DRAW_AREA_Y+DRAW_AREA_HEIGHT);
/*
* Now set pen to draw.
*/
SetAPen(rp, 1L);
/*
* When I use the ruler, I like to jam it up against the left hand side of
* my workbench screen, so that it to measure something on the CLI.
* However, the CLI is offset by a small amount, so I compensate by
* starting the "virtual" area of the ruler a little to the right...
*
* Fill in the offset area that is unused.
*/
RectFill(rp, NULL, OFFSET_START_Y, LEFT_OFFSET,
DRAW_AREA_Y+DRAW_AREA_HEIGHT+1);
/*
* Draw ruler and text
*/
for (x = NULL; x < (w_lim + fsize); x += fsize)
{
/*big tic every 5 chars*/
if ((x % fivec) == NULL) y = BIG_TIC_Y;
else y = SMALL_TIC_Y; /* small tic every char */
Move (rp, x + LEFT_OFFSET, y);
Draw (rp, x + LEFT_OFFSET, RULER_MARK_Y);
/*
* Label ruler.
* The test for position `fivec' (in the Move()) is for centering ``5''
* differently than the centering for two-digit numbers.
*/
if ((x > NULL) && (x < w_lim) && ((x % fivec) == NULL))
{
stci_d(buf,x/fsize);
Move (rp, (x == fivec)
? (x - textWidth + (textWidth/2) + LEFT_OFFSET)
: (x - textWidth + LEFT_OFFSET),
TEXT_Y);
Text (rp, buf, (long) strlen (buf));
}
}
SetAPen(rp,1);
Move(rp,w_lim+LEFT_OFFSET,titleBarHeight);
Draw(rp,w_lim+LEFT_OFFSET,DEF_HEIGHT);
/*
* Wait for gadget activation. No busy-/spin-/wait-loops here!
*/
Wait (1L << window -> UserPort -> mp_SigBit);
/*
* Retrieve LAST message in Message Port
*/
sys_message = GetMsg(window -> UserPort);
class = sys_message -> Class;
code = sys_message -> Code;
ReplyMsg(sys_message);
/*
* Dump uneeded messages (respond only to the last on LIFO queue).
*/
while (sys_message = GetMsg(window -> UserPort))
{
ReplyMsg(sys_message);
}
/*Handle various IDCMP events*/
switch(class)
{
case CLOSEWINDOW:
release_resources();
exit (NORMAL);
case NEWSIZE:
w_lim = (window -> Width) - 1 - LEFT_OFFSET;
break;
case INACTIVEWINDOW:
SetWindowTitles(window,version,"Text Ruler V5.00");
break;
case MENUPICK:
redoWindow=handleMenu(code);
}
}
}
}
/**********************************************************************
*
* cleanup routine
*
* The ``switch'' on resource_state is to assure we don't attempt to
* free something we don't have. Items are released in the reverse
* order they were obtained (by "falling thru" the cases).
*/
void __regargs release_resources()
{
switch (resource_state)
{
case 3: ClearMenuStrip(window);
CloseWindow (window);
case 2: CloseLibrary(GfxBase);
case 1: CloseLibrary(IntuitionBase);
}
if(GadToolsBase != NULL)
CloseLibrary(GadToolsBase);
}
/**********************************************************************
*
* error handler
*/
void __regargs error_exit()
{
release_resources();
exit (FATAL);
}
/*
* Decode menu choice
*/
int __regargs handleMenu(USHORT NUM)
{
struct MenuItem *item;
USHORT menuNum,itemNum;
while(NUM != MENUNULL)
{
menuNum=MENUNUM(NUM);
itemNum=ITEMNUM(NUM);
item=(struct MenuItem *)ItemAddress(&Menu1,NUM);
if(menuNum==0)
if(itemNum==0)
printAboutWindow(); /*About*/
else
{
release_resources(); /*Quit*/
exit(NORMAL);
}
else
if(itemNum==0)
{
changeFSize(); /*Change Scale*/
return(FALSE);
}
else
{
changeScreen(); /*Change Screen*/
return(TRUE);
}
NUM=item->NextSelect;
}
return(0);
}
/*
* Display the About window
*/
void __regargs printAboutWindow()
{
struct Window *aboutWdw;
if((NewAboutWindow.LeftEdge=(screenWidth-NewAboutWindow.Width)/2) > 200)
NewAboutWindow.LeftEdge = 200;
/*
* Determine About window position
*/
NewAboutWindow.TopEdge=(screen->Height-NewAboutWindow.Height)/5;
NewAboutWindow.Height=titleBarHeight-15+ABOUT_WDW_HEIGHT;
/*
* Get the screen the about window will appear on (same as the
* screen the main window is on).
*/
NewAboutWindow.Screen = (struct Screen *) screen;
/*
* Open window
*/
aboutWdw=(struct Window *)OpenWindow(&NewAboutWindow);
if(aboutWdw==NULL)
return;
/*
* Print window text
*/
PrintIText(aboutWdw->RPort,&IText11,0,titleBarHeight-15);
/*
* Wait for input close gadget to be pressed, then close window and
* return.
*/
Wait(1<<aboutWdw->UserPort->mp_SigBit);
CloseWindow(aboutWdw);
return;
}
/*
* Change scale
*/
void __regargs changeFSize()
{
ULONG IDCMPFlags;
IDCMPFlags=window_def.IDCMPFlags;
ModifyIDCMP(window,INACTIVEWINDOW);
for ever
{
/*Wait for IDCMP event*/
Wait (1L << window -> UserPort -> mp_SigBit);
sys_message = GetMsg(window -> UserPort);
class = sys_message -> Class;
ReplyMsg(sys_message);
/*
* If another window was clicked, get the horizontal font size of
* the current font in that window
*/
if(class==INACTIVEWINDOW)
{
if((IntuitionBase->ActiveWindow->RPort->Font->tf_Flags & FPF_PROPORTIONAL) == 0)
fsize=IntuitionBase->ActiveWindow->RPort->Font->tf_XSize;
else
{
/*If the window is using a proportional font, print an error*/
SetWindowTitles(window,version,"Can't change scale: window font is proportional.");
DisplayBeep(window->WScreen);
}
ModifyIDCMP(window,IDCMPFlags);
return;
}
}
}
/*
* Change the screen that the window is displayed on.
*/
void __regargs changeScreen()
{
for ever
{
/*
* Wait for user to click on another window (hopefully in another
* screen).
*/
ModifyIDCMP(window,INACTIVEWINDOW);
Wait (1L << window -> UserPort -> mp_SigBit);
sys_message = GetMsg(window -> UserPort);
class = sys_message -> Class;
ReplyMsg(sys_message);
if(class==INACTIVEWINDOW)
{
/*Get active screen*/
window_def.Screen=screen=IntuitionBase->ActiveScreen;
/*Clear menu strip and close window*/
ClearMenuStrip(window);
CloseWindow(window);
resource_state--;
return;
}
}
}
/*Get arguments from Ruler's icon*/
void __regargs readWBArgs()
{
char *Arg;
struct DiskObject *obj;
/*Open library*/
IconBase=(struct IconBase *)OpenLibrary("icon.library",0L);
if(IconBase == NULL)
{
release_resources();
exit(200);
}
/*Get the icon's information*/
obj=GetDiskObject(WBenchMsg->sm_ArgList[0].wa_Name);
/*Check for size tool type*/
Arg=FindToolType(obj->do_ToolTypes,"size");
if(Arg != NULL)
w=atol(Arg);
/*Check for scale tool type*/
Arg=FindToolType(obj->do_ToolTypes,"scale");
if(Arg != NULL)
fsize=atol(Arg);
/*Check to make sure everything's in bounds*/
if(fsize < 5 || fsize > 50 || w < 12)
exit(300);
/*Free the allocated disk object*/
FreeDiskObject(obj);
CloseLibrary(IconBase); /*Close the icon library*/
return;
}